package org.vectrics.common.struts;

/**
 * Title:        vectrics Server for Logging
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:      vectrics Software Inc.  Service is Built In
 * @author Mike Moore
 * @version 1.0
 */

import java.util.Enumeration;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;

import org.apache.log4j.Logger;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.config.impl.ModuleConfigImpl;
import org.apache.struts.taglib.TagUtils;
import org.vectrics.common.html.BorderTable;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.struts.VectricsTagSupport;

public class ErrorsTag extends VectricsTagSupport {
    
	private static final long serialVersionUID = 180703956755685290L;

	static private transient Logger log = Logger.getLogger(ErrorsTag.class);
	private boolean infoDump = false;
	private int width = 400;
	private String property = null;
	private boolean summary = false; 

    public String makeStartTag()  {
		log.debug("doStartTag() called");
		StringBuffer html = new StringBuffer();		
    	HttpServletRequest request = (HttpServletRequest)super.pageContext.getRequest();
		HttpSession session = super.pageContext.getSession();
		if (infoDump) {
			html.append("<h2>Information</h2>");	
			showAttributes("Request", html, PageContext.REQUEST_SCOPE);
			showAttributes("Session", html, PageContext.SESSION_SCOPE);
			showAttributes("Page", html, PageContext.PAGE_SCOPE);
			showRequestParameters(html);
			html.append("<h3>Servlet Name = " + pageContext.getServletConfig().getServletName() + "</h3>");
		}
		
		ActionMessages errors = null;
		errors = (ActionMessages)pageContext.getAttribute("org.apache.struts.action.ERROR", PageContext.REQUEST_SCOPE);
		if (errors == null) {
			log.debug("doStartTag() - errors is null");
		}
		else {
			if (errors.isEmpty() == false) {
				Table table = new BorderTable();
				table.setWidth(this.getWidth());
				Row row = table.addRow();
				Cell cell = row.addCell();
				cell.setBgColor("#dddddd");
				cell.addElement("<h4>Error(s) with submission:</h4>");
				
				if (getSummary()) {
					cell.addElement("<font class=\"errorMsgFont\">Please fix the errors marked below and submit this form again.</font>");
				}
				else {
					Iterator iter = null;
					if (property == null) {
						iter = errors.get();
					}
					else {
						iter = errors.get(property);
					}
					while (iter.hasNext()) {
						ActionMessage msg = (ActionMessage)iter.next();
						log.debug("Getting key...");
						String key = msg.getKey();
						//html.append("<h4>Found key " + key + "</h4>");
						String bundle = null;
						String locale = Globals.LOCALE_KEY;
						log.debug("message key = " + msg.getKey());
						if (getDebug()) {
							html.append("<h4>Error key = " + msg.getKey() + "</h4>");
						}
						try {
							String message = TagUtils.getInstance().message(pageContext,
												                    bundle,
												                    locale,
												                    msg.getKey(), msg.getValues());	
							if (property == null) {		
			     				cell.addElement("<li><font class=\"errorMsgFont\">" + message + "</font></li>");		
							}
							else {
								html.append("<br><font class=\"errorMsgFont\">" + message + "</font>");
							}
						} catch (Exception ex) {
							log.error("Exception finding error messages", ex);
						}
					}
				}
				
				if (property == null) {
					html.append(table.toString());
					html.append("<br><br>");
				}
			}
			
		}		
		return(html.toString());
    }
    
	private void showAttributes(String scope, StringBuffer html, int scopeInt) {
		Enumeration attrEnum = pageContext.getAttributeNamesInScope(scopeInt);
		if (attrEnum.hasMoreElements()) {
			html.append("<h4>" + scope + " Attributes</h4>");
			Table table = new BorderTable();
			table.setWidth("100%");
			Row hdrRow = table.addRow();
			hdrRow.setDefaultCellFontClass("subFont");
			hdrRow.addCell().addText("Attribute Name");
			hdrRow.addCell().addText("Class");
			hdrRow.addCell().addText("Value");

			while (attrEnum.hasMoreElements()) {
				Row row = table.addRow();
				row.setDefaultCellFontClass("subFont");
				String attr = (String)attrEnum.nextElement();
				row.addCell().addText(attr);
				
				log.debug("Getting attribute value object ...");
				
				Object attrObj = pageContext.getAttribute(attr, scopeInt);

				
				String value = "Exception finding value";
				try {
					value = attrObj.toString();
				}
				catch (Exception ex) {
					log.error("Exception finding value", ex);
				}

				String className = "Exception finding class";
				try {
					className = attrObj.getClass().getName();
				}
				catch (Exception ex) {
					log.warn("Exception finding class", ex);
				}
				
				if (className.equals("org.apache.struts.action.ActionMapping")) {
					ActionMapping actionMapping = (ActionMapping)pageContext.getAttribute(attr, scopeInt);
					value += "<br> - Forward   = " + actionMapping.getForward();
					value += "<br> - Attribute = " + actionMapping.getAttribute();
					value += "<br> - Path      = " + actionMapping.getPath();
					value += "<br> - Input     = " + actionMapping.getInput();
					value += "<br> - Prefix    = " + actionMapping.getPrefix();
					value += "<br> - Roles     = " + actionMapping.getRoles();
					value += "<br> - Type      = " + actionMapping.getType();
					value += "<br> - Name      = " + actionMapping.getName();
					value += "<br> - Include   = " + actionMapping.getInclude();
					value += "<br> - Parameter = " + actionMapping.getParameter();
					value += "<br> - Input Forward = " + actionMapping.getInputForward();
				}
				 				
				if (className.equals("org.apache.struts.config.impl.ModuleConfigImpl")) {
					ModuleConfigImpl moduleConfig = (ModuleConfigImpl)pageContext.getAttribute(attr, scopeInt);
					value += "<br> - Prefix            = " + moduleConfig.getPrefix();
					value += "<br> - Forward Class     = " + moduleConfig.getActionForwardClass();
					value += "<br> - Form Bean Class   = " + moduleConfig.getActionFormBeanClass();
				}
				log.debug("Atribute Displaying...");
				row.addCell().addText(className);
				row.addCell().addText(value);

//				html.append("<p>Attribute:" + attr + "<br> Type: " + className + "<br> Value: " + value + "</p>");
			}
			html.append(table.toString());
		}
		else {
			html.append("<h4>" + scope + "No Attributes</h4>");
			
		}
		log.debug("showAttributes() - done");
	}

	private void showRequestParameters(StringBuffer html) {
		Iterator<String> iter = this.getRequest().getParameterNames().iterator();
		if (iter.hasNext()) {
			html.append("<h4>Request Parameters</h4>");
			Table table = new BorderTable();
			table.setWidth("100%");
			Row hdrRow = table.addRow();
			hdrRow.setDefaultCellFontClass("subFont");
			hdrRow.addCell().addText("Attribute Name");
			hdrRow.addCell().addText("Value");

			while (iter.hasNext()) {
				String paramName = (String)iter.next();
				String paramValue = this.getRequest().getParameter(paramName);
				Row row = table.addRow();
				row.setDefaultCellFontClass("subFont");
				row.addCell().addText(paramName);
				
				log.debug("Getting attribute value object ...");
				
				row.addCell().addText(paramValue);

//				html.append("<p>Attribute:" + attr + "<br> Type: " + className + "<br> Value: " + value + "</p>");
			}
			html.append(table.toString());
		}
		else {
			html.append("<h4>No Request Parameters</h4>");
			
		}
		log.debug("showAttributes() - done");
	}

    
	/**
	 * @return
	 */
	public boolean getDebug() {
		return infoDump;
	}

	/**
	 * @param infoDump
	 */
	public void setDebug(boolean infoDump) {
		this.infoDump = infoDump;
	}

	/**
	 * @return
	 */
	public int getWidth() {
		return width;
	}

	/**
	 * @param width
	 */
	public void setWidth(int width) {
		this.width = width;
	}

	/**
	 * @return
	 */
	public String getProperty() {
		return property;
	}

	/**
	 * @param property
	 */
	public void setProperty(String property) {
		this.property = property;
	}

	/**
	 * @return
	 */
	public boolean getSummary() {
		return summary;
	}

	/**
	 * @param summary
	 */
	public void setSummary(boolean summary) {
		this.summary = summary;
	}

}
